package som.simon.reactor;

import reactor.core.publisher.Flux;
import reactor.core.scheduler.Scheduler;
import reactor.core.scheduler.Schedulers;

import java.io.IOException;

public class ThreadMain {

    public static void main(String[] args) throws IOException {
        Scheduler immediate = Schedulers.immediate();
        Scheduler scheduler = Schedulers.boundedElastic();
        Flux.range(1, 10)
                .log()
                .publishOn(immediate)
                .map(ThreadMain::format)
                .log()
                .subscribeOn(scheduler)
                .subscribe(System.out::println);

        // 无执行上下文（Schedulers.immediate()）：在处理时，提交的内容Runnable 将被直接执行，有效地在当前上运行它们Thread（可以视为“空对象”或无操作Scheduler）。
        //
        // 单个可重用线程 ( Schedulers.single())。请注意，此方法为所有调用者重用同一线程，直到调度程序被释放。如果您想要每个调用专用线程，请Schedulers.newSingle()为每个调用使用。
        //
        // 无界弹性线程池（Schedulers.elastic()）。随着 的引入，这个不再是首选Schedulers.boundedElastic()，因为它有隐藏背压问题并导致太多线程的趋势（见下文）。
        //
        // 有界弹性线程池 ( Schedulers.boundedElastic())。这是为阻塞进程提供自己的线程的便捷方法，这样它就不会占用其他资源。这是 I/O 阻塞工作的更好选择。请参阅 如何封装同步阻塞调用？，但新线程不会给系统带来太大压力。从 3.6.0 开始，根据设置可以提供两种不同的实现：
        //
        //      ExecutorService基于，它重用 PlatformThread`s between tasks. This implementation is like its predecessor `elastic()根据需要创建新的工作池并重用空闲的工作池。闲置时间过长（默认为 60 秒）的工作池也会被丢弃。与它的elastic()前身不同，它对可以创建的支持线程数量有上限（默认为 CPU 核心数量 x 10）。达到上限后提交的最多 100 000 个任务将被排队，并在线程可用时重新调度（当延迟调度时，延迟在线程可用时开始）。
        //
        //      基于每个任务的线程，设计为在VirtualThread实例上运行。要使用该功能，应用程序应在 Java 21+ 环境中运行并将reactor.schedulers.defaultBoundedElasticOnVirtualThreads系统属性设置为true. 一旦设置了上述内容，共享Schedulers.boundedElastic()就会返回一个定制的特定实现BoundedElasticScheduler，以便在类的新实例上运行每个任务 VirtualThread。此实现在行为方面与 ExecutorService基于 的实现类似，但没有空闲池并VirtualThread 为每个任务创建一个新的空闲池。
        //
        // 为并行工作而调整的固定工作人员池 ( Schedulers.parallel())。它会创建与 CPU 核心数量一样多的工作线程。
        System.in.read();
    }

    public static String format(Integer ix) {
         return String.format("%06d", ix);
    }


}
